#ifndef SATELLITEPOS_H
#define SATELLITEPOS_H

#include <QObject>
#include <map>
#include <QHash>
#include <QSet>
#include <QDir>
#include <QDateTime>
#include <QMutex>  //多线程互斥锁
#include <QtNetwork/QNetworkAccessManager>
#include "tle.h"
#include "sgp4pos.h"
#include "eci.h"


class SatellitePos : public QObject
{
    Q_OBJECT
public:
    explicit SatellitePos(QObject *parent = nullptr);

    enum TleSource {
        LocalFiles,
        OnlineSource
    };

    void loadData(const QString& noradPath,
                  const QString& tlePath,
                  TleSource source,
                  bool selectAllNorad,
                  const QSet<int>& targetIds = QSet<int>());

    QSet<int> loadNorad(const QString& dirPath);
    QMap<int, QSet<int>> m_freqToNorad; // 中心频率到NORAD ID集合的映射
    QSet<int> getNoradIdsByFrequency(int freq) const;

signals:
    void progressUpdated(int percentage);  // 进度更新信号
    void errorOccurred(const QString& message); // 错误信号
    void dataReady();

public slots:
    void loadFiles(const QString& noradDir, const QString& tleDir); // 加载文件入口
    QHash<int, libsgp4::Eci> calculatePositions(const QDateTime& qtTime,
                                                const QSet<int>& targetNoradIds); // 计算位置

private slots:
    void handleTleDownload(QNetworkReply* reply);


private:
    // QMutex m_mutex;//线程互斥锁
    QMutex m_tleMutex; // 同时使用本地加载（processLocalTle）和网络加载（handleTleDownload）时，两个线程可能同时修改 m_tleMap，事实上可能性不大，保险起见加锁
    std::map<int, libsgp4::Tle> m_tleMap;// 使用std::map，而不是QMAP
    QSet<int> m_noradSet; // 存储NORAD编号集合
    QNetworkAccessManager m_nam;
    bool m_selectAllMode;

    // 辅助方法
    void loadFrequencyNoradMappings(const QString& noradDir);
    // void processTleFiles(const QString& dirPath, const QSet<int>& noradSet); // 处理TLE文件
    bool validateChecksum(const QString& line);//校验和验证
    // QString preprocessBstar(const QString& line1);// B* 参数处理
    double parseEpochFromTleLine2(const QString& line2); // 从TLE第二行解析epoch时间
    libsgp4::DateTime qdatetimeToSgp4DateTime(const QDateTime& qtTime) const; // 补充声明的时间转换
    bool processLocalTle(const QString& path, const QSet<int>& noradSet);
    void handleIncompleteTle(int groupState, int lineNumber);//处理文件末尾未完成的分组
    void processTleEntry(const QString& fileName,
                         int& lineNumber,
                         QString& name,
                         QString& line1,
                         QString& line2,
                         bool& hasValidTle) ;//处理合法格式的TLE（现将其单独封装为一个函数）

//    void processOnlineTle();
//    void SatellitePos::processNoradFile(const QString& filePath, QSet<int>& noradSet);
    //处理无名称格式TLE
    enum TleLineType { NameLine, Line1, Line2, Unknown };
    TleLineType detectLineType(const QString& line) {
        // if (line.startsWith("0 ")) return NameLine;
        if (line.startsWith("1 ")) return Line1;
        if (line.startsWith("2 ")) return Line2;
        // return Unknown;
        // return (line.length() <= 24 && !line.contains(QRegExp("\\d"))) ? NameLine : Unknown;// 名称行常不含数字
        return NameLine;//其他情况统一视为名称行
    }

};

#endif // SATELLITEPOS_H
